;(function ($) {
	// Determine if widget is included, if not throw an error
	if(typeof($.widget) == "undefind") {
		console.log("$.widget is not defined, did you include jquery-ui?");
		return;
	}
	$.widget("ui.dialogWizard", {
		// Card being displayed
		_index : 0,
		// Cards in the dialog
		_cards : [],
		// Constructor
		_init : function () {
			var self = this, o = self.options, el = self.element;
			
			// Determine if dialog is included, if not throw an error
			if(typeof($.ui.dialog) == "undefined") {
				console.log("$.ui.dialog is not defined, is it included?");
				return;
			}
			
			// Use these buttons by default, if the user specifies
			// other buttons, use those.
			var buttons = {
				buttons: {
					"Cancel" : function(e) {
						$(this).dialogWizard('close');
					},
					"Next" : function (e) {
						$(this).dialogWizard('displayCard', 'next');
					},
					"Previous" : function (e) {
						$(this).dialogWizard('displayCard', 'prev');
					}
				}
			};
			if(typeof(o.buttons) == "undefined") {
				$.extend(true, o, buttons);
				// Create the dialog with muh buttons
				$(el).dialog(o);
				
				// Bind events to add functionality to the buttons
				$(el).bind("showCard", function () {
					var dialogButtons = $(this).parent().children('.ui-dialog-buttonpane').children();
	
					// Disable prev
					if(self._index == 0) {
						$(dialogButtons[2]).addClass("ui-state-disabled").attr("disabled", "disabled");
						$(dialogButtons[1]).removeClass("ui-state-disabled").attr("disabled", "");
					}
					// Disable next
					else if(self._index >= (self._cards.length - 1)) {
						$(dialogButtons[1]).addClass("ui-state-disabled").attr("disabled", "disabled");
						$(dialogButtons[2]).removeClass("ui-state-disabled").attr("disabled", "");
					} else {
						$(dialogButtons[1]).removeClass("ui-state-disabled").attr("disabled", "");
						$(dialogButtons[2]).removeClass("ui-state-disabled").attr("disabled", "");
					}
				});
			} else {
				// Create the dialog with user buttons
				$(el).dialog(o);
			}
			
			// Discover the cards in inventory and display the initial
			// card
			if(self.discoverCards() > 0) {
				self.hideCards();
				self.displayCard();
			}
		},
		// Finds and stores the cards within the element
		discoverCards : function () {
			var self = this, o = self.options, el = self.element, cards = [];
			
			if((cards = $(el).children(o.cardSelector)).length == 0) {
				// No cards found, trigger no cards found event
				self._cards = new Array();
				$(el).trigger("noCardsFound");
			} else {
				self._cards = cards;
				// Cards found, trigger cards found event
				$(el).trigger({
					type : "cardsFound",
					cards : cards,
					amount : cards.length
				}); 
			}
			return cards.length;
		},
		// Hides the cards 
		hideCards : function () {
			var self = this, o = self.options, el = self.element;
			$(self._cards).hide();
			// Trigger cards hidden event
			$(el).trigger("cardsHidden");
			return true;
		},
		// Displays the current card, or the card passed
		displayCard : function (card) {
			var self = this, o = self.options, el = self.element;
			// Fire the before show card event
			$(el).trigger("beforeShowCard");
			
			// Switch between what the user passes
			switch(typeof(card)) {
				case "number" :
					// Determine if the passed card is within range
					if(self._inRange(parseInt(card))) {
						self._index = parseInt(card);
					}
				break;
				case "string" :							
					// Accepted strings, prev, next, first, last
					// +n, -n Where n is a number.
					switch(card) {
						// Current card - 1
						case "prev":
							// Validate it's in range
							if(self._inRange(self._index - 1)) {
								// Set the index to one minus the current
								self._index--;
							}
						break;
						case "next":
							// Validate ...
							if(self._inRange(self._index + 1)) {
								// Set the index to one plus the current
								self._index++;
							}
						break;
						case "first":
							// No need to validate, just set to the first
							self._index = 0;
						break;
						case "last":
							// Same as first
							self._index = self._cards.length - 1;
						break;
						default:
							// Check for + or - n
							var search = /(\+|\-)\s?([0-9]+)/, test = search.test(card), result = search.exec(card), val = 0;
							// doing it this way, because I dont want
							// to eval
							if(test) {
								val = parseInt(result[2]);
								// Determine + or -
								if(result[1] == "+") {
									// Validate range
									if(self._inRange(self._index + val)) {
										self._index = self._index + val;
									}
								} else if(result[1] == "-") {
									// Validate range... again
									if(self._inRange(self._index - val)) {
										self._index = self._index - val;
									}
								}
								// May add * or / later, though I don't
								// know why someone would want it
							}
						break;
					}
				break;
			}
			// Hide the rest of the cards
			$(self._cards).hide();
			
			// Display the current card
			$(self._cards[self._index]).show();
			
			// Trigger the show card event
			$(el).trigger("showCard");
			
			// If it's the final card, trigger a final card event
			if(self._index == self._cards.length - 1) {
				$(el).trigger("finalCard");
			}
		},
		// Closes the window, and dialog
		close : function () {
			var self = this, el = self.element;
			$(el).dialog('close');
			$(el).trigger("close");
		},
		// Kills the dialog
		destroy : function () {
			var self = this, el = self.element, o = self.options;
			self.close();
			
			// Unbind events
			if(typeof(o.buttons) == "undefined") {
				$(el).unbind("showCards");
			}
			
			$(el).dialog('destroy');
		},
		// Determines if the card number is within the range of cards
		_inRange : function (card) {
			var self = this;
			if (card >= 0 && card <= (self._cards.length - 1)) {
				return true;
			} else {
				return false;
			}
		}
		
	});
	$.extend(true, $.ui.wizardDialog, {
		version: ".01",
		defaults: {
			setters : "displayCard close destroy",
			cardSelector : ".card"
		}
	});
})(jQuery);

